// 放大镜的面向对象编程
// 参数1: 放大镜标签对象
// 参数2: 放大镜图片数据信息
class SetGlass{
    constructor(element , imageArr){
        // 存储形参
        this.ele = element;
        this.arr = imageArr;

        // 存储相关数据
        this.show = this.ele.querySelector('.show');
        this.image = this.show.querySelector('img');
        this.mask = this.ele.querySelector('.mask');
        this.list = this.ele.querySelector('.list');
        this.glass = this.ele.querySelector('.glass');

        // 定义属性存储属性值
        this.ulli ;

        // 获取标签占位

        // 父级div标签,左和上的间距
        // 如果 父级div 和 show,div 之间也有距离 也要获取
        // 总之 当前获取的结果应该是 show,div 和 页面的 间距
        this.boxLeft = this.ele.offsetLeft;
        this.boxTop = this.ele.offsetTop;

        // 边框线宽度 show的
        this.borderLeft = this.show.clientLeft;
        this.borderTop = this.show.clientTop;

        // show的 内容+padding
        this.showWidth = this.show.clientWidth;
        this.showHeight = this.show.clientHeight;

        // mask 的占位 宽高
        // display : none 的标签 获取占位 结果是 0
        // 只能通过 css样式获取
        this.maskWidth = parseInt( myGetStyle( this.mask , 'width' ) );
        this.maskHeight = parseInt( myGetStyle( this.mask , 'height' ) );

        // glass 放大区域,宽高 背景图片宽度高度
        this.glassWidth = parseInt( myGetStyle( this.glass , 'width' ) );
        this.glassHeight = parseInt( myGetStyle( this.glass , 'height' ) );

        // 结果是 1600px 1600px 从空格向前截取就是宽度数值 向后截取就是高度数值
        this.str = myGetStyle( this.glass , 'backgroundSize' ) ;
        // 获取空格的索引下标
        this.num = this.str.indexOf(' ');
        // 点 向前截取 就是 宽的数值
        this.glassBgWidth = parseInt( this.str.substring( this.num , -1 ) ) ;
        // 点 后一位向后截取 就是 高的数值
        this.glassBgHeight =parseInt( this.str.substring( this.num+1) );

    }

    // 入口函数
    init(){
        this.setLi();
        this.setInOut();
        this.setClick();
        this.setMove();
    }

    // 方法1 动态生成标签对象
    // 显示区域 是 数组中第一个单元的图片
    // 列表区域 是 数组中所有单元对应生成的li标签
    // 放大区域 背景图片 是 数组中第一个单元的图片
    setLi(){
        // show中img标签src属性值 是 数组中 第一个单元的图片信息
        this.image.setAttribute('src' , `./img/images/${this.arr[0].large}`);
        
        // glass中 背景图片 backgroundImage 的 路径
        this.glass.style.backgroundImage = `url('./img/images/${this.arr[0].large}')`;

        // 列表中的li

        // 字符串 存储 li内容
        let str = '';

        this.arr.forEach((item , key)=>{
            str += key === 0 ? `<li class="active"><img src="./img/images/${item.small}" index="${key}"></li>` : `<li><img src="./img/images/${item.small}" index="${key}"></li>`;

        })

        // 字符串写入 list
        this.list.innerHTML = str;

        // 获取所有的 ul>li
        this.ulli = this.list.querySelectorAll('li');
    }

    // 方法2 鼠标移入移出
    // 鼠标移入移出 显示区域 触发事件
    // 子级标签不需要触发
    setInOut(){
        // 鼠标移入 显示区域
        this.show.addEventListener('mouseenter' , ()=>{
            // 让 遮盖层mask 和 放大区域glass 显示
            this.mask.style.display = 'block';
            this.glass.style.display = 'block';
        })

        // 鼠标移出 显示区域
        this.show.addEventListener('mouseleave' , ()=>{
            // 让 遮盖层mask 和 放大区域glass 隐藏
            this.mask.style.display = 'none';
            this.glass.style.display = 'none';
        })
    }

    // 方法3 点击列表项
    // 点击 列表项中的 图片
    //      清除 所有 li 的 class,active
    //      给 点击的 图片的父级标签li 添加 class,active
    //      获取 点击图片 对应 的索引下标 
    //      从数组中获取数据 设定 显示区域图片内容 放大区域背景图片内容
    // 给父级ul标签 添加点击事件 通过 事件委托 完成效果
    setClick(){
        this.list.addEventListener('click' , e=>{
            // 如果点击的标签 标签名称是 IMG 点击的是图片
            if( e.target.tagName === "IMG" ){
                // 给所有的 ul>li 清除 class,active
                this.ulli.forEach( item=>{
                    item.classList.remove('active');
                } )

                // 给 点击的 标签 也就是 e.target这个图片 的父级 li 添加 class,active
                e.target.parentNode.classList.add('active');

                // 获取 点击标签 index属性值 也就是 索引下标
                // 从 数组中 获取 数据 设定给 show中img标签src属性 和 glass放大区域背景图片

                let index = e.target.getAttribute('index')-0;

                // show中img标签src属性值 是 数组中 第一个单元的图片信息
                this.image.setAttribute('src' , `./img/images/${this.arr[index].large}`);

                // glass中 背景图片 backgroundImage 的 路径
                this.glass.style.backgroundImage = `url('./img/images/${this.arr[index].large}')`;
            }
        })
    }

    // 方法4 鼠标拖拽
    // 1, 遮盖层 跟随 鼠标移动
    setMove(){
        // 给 show 添加鼠标移动事件
        this.show.addEventListener('mousemove' , e=>{
            // 1, 获取坐标的数值
            // 定位数值 = 鼠标的page - div的外边距 - 边框线 - 遮盖层宽高/2
            let x = e.pageX - this.boxLeft - this.borderLeft  -  this.maskWidth/2;         
            let y = e.pageY - this.boxTop - this.borderTop  -  this.maskHeight/2;
            
            // 2, 设定极值
            x = x < 0 ? 0 : x;
            y = y < 0 ? 0 : y;

            x = x > this.showWidth - this.maskWidth ? this.showWidth - this.maskWidth : x;
            y = y > this.showHeight - this.maskHeight ? this.showHeight - this.maskHeight : y;

            // 3, 给遮盖层定位
            this.mask.style.left = x + 'px';
            this.mask.style.top = y + 'px';


            // 4, glass背景图片的定位

            // 定位的数值是 等比例放大的
            let bgX = x*( this.glassBgWidth / this.showWidth );
            let bgY = y*4;

            // 定位的方向 是 相反的
            this.glass.style.backgroundPosition = `-${bgX}px -${bgY}px`;
        })



    }
}